﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Objects;
using BusinessBingo.Common;
using BusinessBingo.Common.Interfaces;
using BusinessBingo.Data.DataLoadOptions;
using BusinessBingo.Data.DataOrderOptions;
using BusinessBingo.Data.Filter;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;

namespace BusinessBingo.Data
{
    public class EFUserRepository : EFBaseRepository, IUserRepository
    {
        public EFUserRepository(IUnitOfWork unitOfWork, IGuid portalGuid)
            : base(unitOfWork, portalGuid)
        {
        }

        public IList<Model.User> GetItems(UserDataLoadOptions dlo, UserDataOrderOptions doo, UserFilter filter)
        {
            ObjectQuery<SessionUser> query = this.GetQuery(dlo, doo, filter);
            IList<SessionUser> items = query.ToList();

            IList<Model.User> result = new List<Model.User>();

            foreach (SessionUser item in items)
            {
                result.Add(Mapping.MapSessionUser(item));
            }

            return result;
        }

        public User AddItem(Model.User item)
        {
            Data.SessionUser sessionUser = Mapping.MapSessionUser(item);
            sessionUser.Id = this._portalGuid.New;
            sessionUser.GroupId = item.GroupId;
            this._context.SessionUsers.AddObject(sessionUser);

            item.Id = sessionUser.Id;
            return item;
        }

        public ObjectQuery<Data.SessionUser> GetQuery(UserDataLoadOptions dlo, UserDataOrderOptions doo, UserFilter filter)
        {
            ObjectQuery<SessionUser> query = this._context.SessionUsers;
            
            return query.LoadWith(dlo).FilterFor(filter).OrderBy(doo);
        }

        public int GetItemsCount(UserFilter filter)
        {
            ObjectQuery<SessionUser> query = this.GetQuery(null, null, filter);
            return query.Count();
        }
    }

    internal static class UserQueryExtensions
    {
        public static ObjectQuery<SessionUser> FilterFor(this ObjectQuery<SessionUser> query, UserFilter filter)
        {
            if (filter == null) return query;

            if (filter.WithId.HasValue == true)
                query = (ObjectQuery<SessionUser>)query.Where(x => x.Id.Equals(filter.WithId.Value));

            return query;
        }
        
        public static ObjectQuery<SessionUser> LoadWith(this ObjectQuery<SessionUser> query, UserDataLoadOptions dlo)
        {
            UserDataLoadOptions sdlo = (UserDataLoadOptions) dlo;

            if (sdlo == null) return query;

            return query;
        }

        public static ObjectQuery<SessionUser> OrderBy(this ObjectQuery<SessionUser> query, UserDataOrderOptions doo)
        {
            return query;
        }
    }
}